import sys
import random
import matplotlib
from utils.tools import *
import pathlib
from PIL import ImageEnhance
import PIL
import os
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QSizePolicy, QWidget
from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from matplotlib.patches import Polygon, Rectangle, Circle, Arrow, ConnectionPatch,Ellipse,FancyBboxPatch
import matplotlib.pyplot as plt
import skimage as ski
from skimage import transform

class Plot_Config():
    TV = None
    auto_recording = False
    size_mul = 1
    V_rate = 1
    scale_rate = 1
    show_V = False
    save_source = True
    save_prediction = True
    save_as_video = True
    cal_distance = False
    mix_enhancement_mode = False
    data_enhancement_args = Data_enhancement_configure()
    data_enhancement_choice = Data_enhancement_sign(0)
    debug_mode = False
    st_frame = 0
    ed_frame = 0
    last_bar_value = None
    cal_V_mode = Cal_V_mode.default
    arrow_mode = Arrow_mode.Player_Control
    TV_anchor_deta = 0
    global vision_enhancement
    global manual_rectangle
    manual_rectangle_Hheight = 20
    manual_rectangle_Hwidth = 20
    hide_name = False
    FPS_limiter = DEFAULT_FPS
    FPS_timer = time.time()


class MyMplCanvas(FigureCanvas):
    """FigureCanvas的最终的父类其实是QWidget。"""
    
    startx = 0
    starty = 0
    image = None #dataset类
    img = None#np.array的图片
    mPress=False    
    svg_list = []
    config = Plot_Config()

    def __init__(self, parent=None, width=5, height=4, dpi=100):

        # 配置中文显示
        plt.rcParams['font.family'] = ['SimHei']  # 用来正常显示中文标签
        plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

        self.fig = Figure(figsize=(width, height), dpi=dpi)  # 新建一个figure
        self.axes = self.fig.add_subplot(111)  # 建立一个子图

        #将self.axex铺满整个Figure      
        FigureCanvas.__init__(self, self.fig)
        self.axes.set_position([0, 0, 1, 1])
        self.setParent(parent)
        self.axes.axis('off')

        #定义FigureCanvas的尺寸策略，这部分的意思是设置FigureCanvas，使之尽可能的向外填充空间。
        # FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        #设置FigureCanvas与画布之间没有边距
        self.fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
        

            
        #设置滚动放大缩小，右键移动
        self.fig.canvas.mpl_connect('button_press_event', self.call_move)
        self.fig.canvas.mpl_connect('button_release_event', self.call_move)
        # fig.canvas.mpl_connect('draw_event', call_move)
        self.fig.canvas.mpl_connect('motion_notify_event', self.call_move)
        self.fig.canvas.mpl_connect('scroll_event', self.call_scroll)
        self.fig.canvas.mpl_connect('key_release_event', self.on_key_press)
        
    
        # self.start_plot('image.jpg')

    def start_plot(self, image, config=None):
        self.axes.clear()

        path = pathlib.Path(image.img_path)
        if(config == None):
            self.image = image
            self.config = Plot_Config()#存储画图相关的参数
            self.img = PIL.Image.open(path)#读取图片
            
        enhance_img = self.img #数据增强后的图片

        #改变亮度        
        if self.config.V_rate != 1:
            Vr = self.config.V_rate
            enhancer = ImageEnhance.Brightness(enhance_img)
            enhance_img = enhancer.enhance(Vr)

        self.axes.imshow(enhance_img)
        
        #绘制四个关键点连线
        if(os.path.exists(path.with_suffix('.txt'))):
            with open(path.with_suffix('.txt'), 'r') as f:
                lines = f.readlines()
                for line in lines:
                    coords = list(map(float, line.strip('\n').split(' ')))
                    x = [coords[0]*640, coords[2]*640, coords[4]*640, coords[6]*640, coords[0]*640]
                    y = [coords[1]*640, coords[3]*640, coords[5]*640, coords[7]*640, coords[1]*640]

                    # 绘制四边形
                    self.axes.plot(x,y)

        self.fig.canvas.draw_idle()
    
    def call_move(self, event):
        if event.name=='button_press_event':
            axtemp=event.inaxes
            if axtemp and event.button==3:
                self.mPress = True
                self.startx=event.xdata
                self.starty=event.ydata
            elif axtemp and event.button==1:
                event.canvas.widgetlock.release(event.key)
                event.canvas.setFocus()
        elif event.name=='button_release_event':
            axtemp=event.inaxes
            if axtemp and event.button==3:
                self.mPress=False
        elif event.name=='motion_notify_event':
            axtemp=event.inaxes
            if axtemp and event.button==3 and self.mPress:
                x_min, x_max = axtemp.get_xlim()
                y_min, y_max = axtemp.get_ylim()
                w=x_max-x_min
                h=y_max-y_min
                # print(event)
                # 移动
                mx=event.xdata-self.startx
                my=event.ydata-self.starty

                axtemp.set(xlim=(x_min-mx, x_min-mx+w))
                axtemp.set(ylim=(y_min-my, y_min-my+h))

                self.fig.canvas.draw_idle()

        return

    def call_scroll(self, event):
        axtemp=event.inaxes
        # 计算放大缩小后， xlim 和ylim
        if axtemp:
            x_min, x_max = axtemp.get_xlim()
            y_min, y_max = axtemp.get_ylim()
            w = x_max - x_min
            h = y_max - y_min
            curx=event.xdata
            cury=event.ydata
            curXposition=(curx - x_min) / w
            curYposition=(cury - y_min) / h
            if event.button == 'down':
                w = w*1.1
                h = h*1.1
            elif event.button == 'up':
                w = w/1.1
                h = h/1.1
            newx=curx - w*curXposition
            newy=cury - h*curYposition
            axtemp.set(xlim=(newx, newx+w))
            axtemp.set(ylim=(newy, newy+h))
            self.fig.canvas.draw_idle()  # 绘图动作实时反映在图像上

    def on_key_press(self, event):
        axtemp=event.inaxes
        if(axtemp):            
            if event.key == '8':
                self.config.V_rate += 0.1
                self.start_plot(self.image, self.config)
            elif event.key == '2':
                self.config.V_rate -= 0.1
                self.start_plot(self.image, self.config)
            elif event.key == '5':
                self.config.V_rate = 1
                self.start_plot(self.image, self.config)
            elif event.key == 'q':
                self.open_current_file(0)
            elif event.key == 'w':
                self.open_current_file(1)
            elif event.key == 'e':
                self.open_current_file(2)

    def open_current_file(self, choice=0):
        """
        打开当前文件

        Args:
            choice (int, optional):0 for image, 1 for label, 2 for folder.默认为0。
            frame (int, optional): 帧数。默认为0。
        """
        target_path = None  #目标路径

        if choice == 0:
            #打开图片文件
            target_path = self.image.img_path
        elif choice == 1:
            #打开标签文件
            target_path = self.image.label_path
        elif choice == 2:
            #打开文件夹            
            target_path =  self.image.img_path.parent
            if target_path.stem == 'images':
                target_path =  target_path.parent.parent
        
        if os.name == 'nt':  
                os.startfile(target_path)
        else:  
            os.system(f'xdg-open {str(target_path)}')

